package store.lunangangster.engine.impl.repository;

import store.lunangangster.bpmn.model.BpmnModel;
import store.lunangangster.bpmn.model.Process;
import store.lunangangster.engine.ProcessEngineConfiguration;
import store.lunangangster.engine.bpmn.parser.BpmnParser;
import store.lunangangster.engine.impl.entity.ProcessDefinitionEntity;
import store.lunangangster.engine.repository.ProcessDefinition;

public class DeployCacheManager {

  protected ProcessEngineConfiguration processEngineConfiguration;
  protected DeploymentCache<ProcessDefinitionCacheEntry> processDefinitionCache;

  public DeployCacheManager(ProcessEngineConfiguration processEngineConfiguration) {
    this.processEngineConfiguration = processEngineConfiguration;
    this.processDefinitionCache = processEngineConfiguration.getDeploymentCache();
  }

  public void putToCache(ProcessDefinitionCacheEntry processDefinitionCacheEntry) {
    if (processDefinitionCacheEntry != null) {
      // using ProcessDefinition's id for Cache's key
      processDefinitionCache.set(processDefinitionCacheEntry.getProcessDefinition().getId(), processDefinitionCacheEntry);
    }
  }

  public void removeFromCache(String processDefinitionId) {
    processDefinitionCache.remove(processDefinitionId);
  }

  public ProcessDefinitionCacheEntry findInCache(String key) {
    return processDefinitionCache.get(key);
  }

  public ProcessDefinitionCacheEntry findInCacheByProcessDefinition(ProcessDefinition processDefinition) {
    if (processDefinition != null) {
      return processDefinitionCache.get(processDefinition.getId());
    }
    return null;
  }

  /**
   * 将DeploymentParse对象中保存的ProcessDefinition、BpmnModel等信息重新加载到
   * 缓存中
   * @param deploymentParse 待加载到缓存中的对象
   */
  public void updateCache(DeploymentParse deploymentParse) {
    for (ProcessDefinitionEntity processDefinition : deploymentParse.getProcessDefinitionEntities()) {
      BpmnParser bpmnParser;
      BpmnModel bpmnModel;
      Process process;

      bpmnParser = deploymentParse.getBpmnParsersByProcessDefinition(processDefinition);
      bpmnModel = bpmnParser == null ? null : bpmnParser.getBpmnModel();
      process = null;
      if (bpmnModel != null) {
        for (Process proc : bpmnModel.getProcesses()) {
          if (proc.getId().equals(processDefinition.getKey())) { // Process's id <=> ProcessDefinition's key
            process = proc;
            break;
          }
        }
      }
      ProcessDefinitionCacheEntry processDefinitionCacheEntry = new ProcessDefinitionCacheEntry(
          processDefinition, bpmnModel, process);
      // ProcessDefinitionCache中
      putToCache(processDefinitionCacheEntry);
    }
  }

  public DeploymentCache<ProcessDefinitionCacheEntry> getProcessDefinitionCache() {
    return processDefinitionCache;
  }
}
